<!doctype html>
<html class="no-js" lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>
    
  项目笔记 - NeilBlog
  
  </title>
  
  
  <link href="atom.xml" rel="alternate" title="NeilBlog" type="application/atom+xml">
    <link rel="stylesheet" href="asset/css/foundation.min.css" />
    <link rel="stylesheet" href="asset/css/docs.css" />
    <script src="asset/js/vendor/modernizr.js"></script>
    <script src="asset/js/vendor/jquery.js"></script>
  <script src="asset/highlightjs/highlight.pack.js"></script>
  <link href="asset/highlightjs/styles/github.css" media="screen, projection" rel="stylesheet" type="text/css">
  <script>hljs.initHighlightingOnLoad();</script>
<script type="text/javascript">
  function before_search(){
    var searchVal = 'site: ' + document.getElementById('search_input').value;
    document.getElementById('search_q').value = searchVal;
    return true;
  }
</script>
  </head>
  <body class="antialiased hide-extras">
    
    <div class="marketing off-canvas-wrap" data-offcanvas>
      <div class="inner-wrap">


<nav class="top-bar docs-bar hide-for-small" data-topbar>


  <section class="top-bar-section">
  <div class="row">
      <div style="position: relative;width:100%;"><div style="position: absolute; width:100%;">
        <ul id="main-menu" class="left">
        
        <li id=""><a target="self" href="index.html">Home</a></li>
        
        <li id=""><a target="_self" href="archives.html">Archives</a></li>
        
        </ul>

        <ul class="right" id="search-wrap">
          <li>
<form target="_blank" onsubmit="return before_search();" action="https://google.com/search" method="get">
    <input type="hidden" id="search_q" name="q" value="" />
    <input tabindex="1" type="search" id="search_input"  placeholder="Search"/>
</form>
</li>
          </ul>
      </div></div>
  </div>
  </section>

</nav>

        <nav class="tab-bar show-for-small">
  <a href="javascript:void(0)" class="left-off-canvas-toggle menu-icon">
    <span> &nbsp; NeilBlog</span>
  </a>
</nav>

<aside class="left-off-canvas-menu">
      <ul class="off-canvas-list">
        
        <li><a target="self" href="index.html">Home</a></li>
        
        <li><a target="_self" href="archives.html">Archives</a></li>
        

    <li><label>Categories</label></li>

        
            <li><a href="Python.html">Python</a></li>
        
            <li><a href="opentstack-neutron.html">opentstack-neutron</a></li>
        
            <li><a href="%E6%8A%80%E6%9C%AF%E5%91%A8%E8%BE%B9.html">技术周边</a></li>
        
            <li><a href="%E9%A1%B9%E7%9B%AE%E7%AC%94%E8%AE%B0.html">项目笔记</a></li>
         

      </ul>
    </aside>

<a class="exit-off-canvas" href="#"></a>


        <section id="main-content" role="main" class="scroll-container">
        
       

 <script type="text/javascript">
	$(function(){
		$('#menu_item_index').addClass('is_active');
	});
</script>
<div class="row">
	<div class="large-8 medium-8 columns">
		<div class="markdown-body home-categories">
		
			<div class="article">
                <a class="clearlink" href="15622929808447.html">
                
                  <h1>netconf client通信框架</h1>
                  <div class="a-content">
                      
                      <div class="a-content-text">
                        
                        	<h2 id="toc_0">需求</h2>

<ul>
<li>支持并发处理，即保证多线程同时调用netconf发送消息能够被处理</li>
<li>能够返回错误结果信息给调用者-&gt;需要解析响应的xml信息</li>
<li>支持netconf消息排队处理<br/>
## 设计</li>
<li>使用celery+redis框架实现任务调度</li>
<li>提供netconf client接口
<ul>
<li>初始化（启动celery worker线程；可以通过shell启动）
<ul>
<li>注册接口 uninc_init()；提供登录设备相关信息</li>
</ul></li>
<li>提供get、set接口
<ul>
<li>实现向设备下发uninc_set_config()</li>
<li>从设备获取配置uninc_get_config()</li>
</ul></li>
</ul></li>
</ul>

<p><img src="media/15622929808447/15623083336434.jpg" alt=""/></p>

<h2 id="toc_1">问题!</h2>

<p>celery创建一个task，使用shell启动task<br/>
celery实现一个app，使用shell启动app，两者有啥区别？</p>

                        
                      </div>
                  </div>
                </a>
                <div class="read-more clearfix">
                  <div class="more-left left">
                  
                    <span class="date">2019/7/5</span>
                    <span>posted in&nbsp;</span> 
          				  
          					    <span class="posted-in"><a href='%E9%A1%B9%E7%9B%AE%E7%AC%94%E8%AE%B0.html'>项目笔记</a></span>
          				   
                  </div>
                  <div class="more-right right">
                  <span class="comments">
                      

                       
                  </span>
                  </div>
                </div>
              </div><!-- article -->
        
			<div class="article">
                <a class="clearlink" href="15620552731750.html">
                
                  <h1>neutron agent 使用netconf向设备下发配置</h1>
                  <div class="a-content">
                      
                      <div class="a-content-text">
                        
                        	<p>本文将从why、what、how、where 几个方面介绍netconf</p>

<h2 id="toc_0">Why（为什么使用netconf下发配置？）</h2>

<ul>
<li>netconf本身就是为网络设备管理诞生的命令</li>
<li>厂商网络设备管理均使用netconf命令下发</li>
<li>netconf可以支持连续下发多条配置</li>
<li>netconf可以支持批量下发配置</li>
<li>netconf可以支持出错回滚功能</li>
<li>netconf可以支持事务操作（h3c不支持，但h3c支持配置保存以及配置回滚，可以先保存下发前配置，配置失败回滚到下发之前）</li>
<li>netconf支持事件订阅等</li>
</ul>

<hr/>

<ul>
<li>h3c支持通过netconf下发命令行，可以完全替代ssh下发命令。</li>
</ul>

<h2 id="toc_1">What（netconf是什么鬼，能干吗？）</h2>

<blockquote>
<p>NETCONF(Network Configuration Protocol，网络配置协议)是一种基于XML的网络管理协议， 他提供了一种可编程的、对网络设备进行配置和管理的方法。用户可以通过该协议设置属性、获取 属性值、获取统计信息等。这使得他在第三方软件的开发上非常便利，很容易开发出在混合不同厂 商、不同设备的环境下的特殊定制的网管软件。（h3c官方文档）</p>
</blockquote>

<h3 id="toc_2">netconf 协议详解</h3>

<blockquote>
<p>引用：<a href="https://blog.csdn.net/anzheangel/article/details/78885880">https://blog.csdn.net/anzheangel/article/details/78885880</a></p>

<h4 id="toc_3">概述</h4>

<p><img src="media/15620552731750/SouthEast.png" alt="SouthEast"/><br/>
NETCONF协议分为四层：由下至上分别是安全传输层，消息层，操作层和内容层<br/>
网络模型分为两类：状态数据、配置数据。</p>

<ul>
<li>状态数据一般指server（设备）的固有属性数据和当前运行的状态数据等，这类数据仅能查询。</li>
<li>配置数据则是指由用户（以某种方式）配置到server上的数据。配置数据本身又可以存在多个数据库。
<ul>
<li><running/>库用于保存当前已经生效的配置；（当前操作h3c设备只有running）</li>
<li><candidate/>用于保存可以提交为生效的数据；</li>
<li><startup/>用于保存启动时的配置数据。</li>
</ul></li>
</ul>
</blockquote>

<h4 id="toc_4">安全层</h4>

<p>NETCONF的第一大优势就是其从协议层面就已经规定其传输层必须使用带有安全加密的通信协议。<br/>
H3C支持的协议：</p>

<ul>
<li>非FIPS模式下:
<ul>
<li>NETCONF 支持 Telnet、SSH 和 Console 等 CLI 登录方式/协议，即 NETCONF over SSH、NETCONF over Telnet 和 NETCONF over Console</li>
<li>NETCONF 支持封装成 SOAP(Simple Object Access Protocol，简 单对象访问协议)报文后通过 HTTP 或 HTTPS 协议传输，即 NETCONF over SOAP over HTTP 和 NETCONF over SOAP over HTTPS</li>
</ul></li>
<li>FIPS模式下:
<ul>
<li>NETCONF 支持 SSH 和 Console 等 CLI 方式/协议，即 NETCONF<br/>
over SSH 和 NETCONF over Console</li>
<li>NETCONF 支持封装成 SOAP 报文后通过 HTTPS 协议传输，即</li>
<li>NETCONF over SOAP over HTTPS</li>
</ul></li>
</ul>

<h4 id="toc_5">消息层</h4>

<p>消息层分为三种类型：分别是hello， rpc和rpc-reply, notification</p>

<ul>
<li>hello消息
<ul>
<li><hello>仅用于会话刚刚建立时netconf-server和netconf-client之间进行能力交换。</li>
<li>server和client需要在会话建立后互相发送<hello>消息，并在<hello>消息中携带自身支持的能力，以及支持的netconf协议的版本号，server和client根据自身和对方的能力信息协商使用的netconf版本。</li>
<li>一般来说，C/S双方互发<hello>且协商版本成功后，认为netconf会话建立成功。</li>
<li>建立连接之后，server会分配给client一个session信息，client需要在后续报文中携带此session信息，相当于http中的session信息</li>
</ul></li>
</ul>

<p>(1) XPath Capability <br/>
　　该能力表示client可以在filter中使用XPath表达式作为过滤条件 ncclient是支持的<br/>
　　Capability Identifier: <br/>
　　urn:ietf:params:netconf:capability:xpath:1.0 <br/>
(2) Writable-Running Capability <strong>个人理解一定支持的能力</strong><br/>
　　该能力表示server支持直接对<running/>库进行修改操作。 <br/>
　　Capability Identifier: <br/>
　　urn:ietf:params:netconf:capability:writable-running:1.0 <br/>
(3) Candidate Configuration Capability <strong>此能力h3c并不支持</strong><br/>
　　该能力表示server具有一个candidate数据库，并且可以将candidate数据库中的配置提交生效并更新running数据库 <br/>
　　Capability Identifier: <br/>
　　urn:ietf:params:netconf:capability:candidate:1.0 <br/>
(４) Rollback-on-Error Capability <strong>h3c支持此能力，如果需要用到必须确保一起生效时可以使用此能力信息。</strong><br/>
　　<strong>该能力表示server在执行client发送的配置数据出错后可以进行回滚</strong> <br/>
　　Capability Identifier: <br/>
　　urn:ietf:params:netconf:capability:rollback-on-error:1.0 <br/>
(５) Validate Capability <br/>
　　该能力表示server可以校验client发送的配置数据是否正确 <br/>
　　Capability Identifier: <br/>
　　urn:ietf:params:netconf:capability:validate:1.1 <br/>
(６) Distinct startup Capability <strong>h3c不支持</strong><br/>
　　该能力表示server有一个startup数据库，用于保存启动配置 <br/>
　　Capability Identifier: <br/>
　　urn:ietf:params:netconf:capability:startup:1.0</p>

<ul>
<li>rpc、rpc-reply消息
<ul>
<li><rpc>是由netconf-client发起的发送到netconf-server的消息。用于client请求server执行某项具体的操作。</li>
<li><rpc>包含一个强制属性”message-id”，这个id是一个单调递增的正整数，同一会话内不能重复。该id用于<rpc>和<rpc-reply>的配对。</li>
<li><rpc-reply>是有netconf-server发送给netconf-client的rpc响应。不能主动发起，仅能在收到<rpc>之后回复，切必须携带与收到的rpc相同的message-id。 </li>
<li>在<rpc-reply>定义了两种默认的元素分别是<ok>和<rpc-error>。<ok>表示为定义响应内容的rpc执行成功，而<rpc-error>表示rpc执行失败。 
<em>目前ncclient提供manager api和rpc层接口，个人理解如果调用manager层不用关心rpc 中的message等信息，manager会自动填充，而rpc接口就要填充rpc/rpc-reply字段</em>
<code>
　　NETCONF&lt;rpc&gt;requests MUST be processed serially by the managed device. Additional&lt;rpc&gt;requests MAY be sent before previous ones have been completed. The managed device MUST send responses only in the order the requests were received.  <br/>
　　个人理解：<br/>
　　1. netconf-client必须保证server收到的rpc请求的顺序和message-id的顺序是一致的。 <br/>
　　2. netconf-server在能保证数据不冲突的前提下可以并行处理收到的rpc请求。 <br/>
　　3. netconf-server在发送&lt;rpc-reply&gt;时必须严格按照收到的&lt;rpc&gt;的顺序。
</code>
在netconf的1.0版本中还没有加入Notification相关的内容，而在1.1版本已经将RFC5277(NETCONF Event Notifications)囊落在内了。支持Notification上报的netconf-server需在能力交换时上报能力： <br/>
　　“urn:ietf:params:netconf:capability:notification:1.0” <br/>
几个关键的知识点： <br/>
　　1. Netconf的通知采用的是订阅发布机制，server仅会向发送过订阅请求的client发送通知。<br/>
　　2. Netconf的通知是以Stream进行分类的，不同类的Stream以不同的stream-name进行区分。netconf-server默认需要支持的stream-name是”NETCONF”。 <br/>
　　3. client不能重复下发订阅，即同一Stream的订阅不能重复下发，也不能同时订阅多个Stream，订阅可以设置定时取消，如果没有设置终止时间，取消订阅需要使用close-session或者kill-session。定时取消的订阅netconf的会话还是激活的，而使用close-session或者kill-session来取消的话，netconf会话会关闭。 </li>
</ul></li>
</ul>

<h4 id="toc_6">操作层</h4>

<p>操作层仅承载在仅<rpc>和<rpc-reply>消息上，<hello>和<notification>消息无操作层。NETCONF协议规定了9种简单的rpc操作，同时也支持用户自定义rpc操作。</p>

<ul>
<li><get>用于查询状态数据，另外如果server支持能力:urn:ietf:params:netconf:capability:xpath:1.0则还可以使用filter进行条件查询
举例：</li>
</ul>

<pre><code class="language-text">&lt;rpc message-id=&quot;101&quot;
    xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;
    &lt;get&gt;
        &lt;filter type=&quot;subtree&quot;&gt;
            &lt;top
                xmlns=&quot;http://example.com/schema/1.2/stats&quot;&gt;
                &lt;interfaces&gt;
                    &lt;interface&gt;
                        &lt;ifName&gt;eth0&lt;/ifName&gt;
                    &lt;/interface&gt;
                &lt;/interfaces&gt;
            &lt;/top&gt;
        &lt;/filter&gt;
    &lt;/get&gt;
&lt;/rpc&gt;
&lt;rpc-reply message-id=&quot;101&quot; xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;
    &lt;data&gt;
        &lt;top xmlns=&quot;http://example.com/schema/1.2/stats&quot;&gt;
            &lt;interfaces&gt;
                &lt;interface&gt;
                    &lt;ifName&gt;eth0&lt;/ifName&gt;
                    &lt;ifInOctets&gt;45621&lt;/ifInOctets&gt;
                    &lt;ifOutOctets&gt;774344&lt;/ifOutOctets&gt;
                &lt;/interface&gt;
            &lt;/interfaces&gt;
        &lt;/top&gt;
    &lt;/data&gt;
&lt;/rpc-reply&gt;
</code></pre>

<ul>
<li><get-config>
<p>　　用于查询配置数据，可以通过 <source/>来指定不同的配置库，例如：</p>
<pre><code class="language-text">&lt;rpc message-id=&quot;101&quot;xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;
&lt;get-config&gt;<br/>
    &lt;source&gt;<br/>
        &lt;running/&gt;<br/>
    &lt;/source&gt;<br/>
    &lt;filter type=&quot;subtree&quot;&gt;<br/>
        &lt;top xmlns=&quot;http://example.com/schema/1.2/config&quot;&gt;<br/>
            &lt;users/&gt;<br/>
        &lt;/top&gt;<br/>
    &lt;/filter&gt;<br/>
&lt;/get-config&gt;<br/>
&lt;/rpc&gt;<br/>
&lt;rpc-reply message-id=&quot;101&quot; xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;<br/>
&lt;data&gt;<br/>
    &lt;top xmlns=&quot;http://example.com/schema/1.2/config&quot;&gt;<br/>
        &lt;users&gt;<br/>
            &lt;user&gt;<br/>
                &lt;name&gt;root&lt;/name&gt;<br/>
                &lt;type&gt;superuser&lt;/type&gt;<br/>
                &lt;full-name&gt;Charlie Root&lt;/full-name&gt;<br/>
                &lt;company-info&gt;<br/>
                    &lt;dept&gt;1&lt;/dept&gt;<br/>
                    &lt;id&gt;1&lt;/id&gt;<br/>
                &lt;/company-info&gt;<br/>
            &lt;/user&gt;<br/>
            &lt;!-- additional &lt;user&gt; elements appear here... --&gt;<br/>
        &lt;/users&gt;<br/>
    &lt;/top&gt;<br/>
&lt;/data&gt;<br/>
&lt;/rpc-reply&gt;
</code></pre></li>
<li><edit-config>
<p>　　用于对指定配置数据库的内容进行修改，支持以下几种操作： <br/>
　　merge: 合并操作，此操作为默认操作。 <br/>
　　replace: 替换操作，如果对象已经存在则替换，不存在则创建。 <br/>
　　create: 创建操作，如果对象已经存在，则报错误“data-exists”。 <br/>
　　delete: 删除操作，如果对象存在则删除，不存在则报错 “data-missing”。 <br/>
　　remove: 删除操作，如果对象存在则删除，不存在则忽略。 <br/>
举例：</p>
<pre><code class="language-text">&lt;rpc message-id=&quot;101&quot;
xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;<br/>
&lt;edit-config&gt;<br/>
    &lt;target&gt;<br/>
        &lt;running/&gt;<br/>
    &lt;/target&gt;<br/>
    &lt;config<br/>
        xmlns:xc=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;<br/>
        &lt;top<br/>
            xmlns=&quot;http://example.com/schema/1.2/config&quot;&gt;<br/>
            &lt;interface xc:operation=&quot;replace&quot;&gt;<br/>
                &lt;name&gt;Ethernet0/0&lt;/name&gt;<br/>
                &lt;mtu&gt;1500&lt;/mtu&gt;<br/>
                &lt;address&gt;<br/>
                    &lt;name&gt;192.0.2.4&lt;/name&gt;<br/>
                    &lt;prefix-length&gt;24&lt;/prefix-length&gt;<br/>
                &lt;/address&gt;<br/>
            &lt;/interface&gt;<br/>
        &lt;/top&gt;<br/>
    &lt;/config&gt;<br/>
&lt;/edit-config&gt;<br/>
&lt;/rpc&gt;<br/>
&lt;rpc message-id=&quot;101&quot;<br/>
xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;<br/>
&lt;edit-config&gt;<br/>
    &lt;target&gt;<br/>
        &lt;running/&gt;<br/>
    &lt;/target&gt;<br/>
    &lt;default-operation&gt;none&lt;/default-operation&gt;<br/>
    &lt;config<br/>
        xmlns:xc=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;<br/>
        &lt;top<br/>
            xmlns=&quot;http://example.com/schema/1.2/config&quot;&gt;<br/>
            &lt;protocols&gt;<br/>
                &lt;ospf&gt;<br/>
                    &lt;area&gt;<br/>
                        &lt;name&gt;0.0.0.0&lt;/name&gt;<br/>
                        &lt;interfaces&gt;<br/>
                            &lt;interface xc:operation=&quot;delete&quot;&gt;<br/>
                                &lt;name&gt;192.0.2.4&lt;/name&gt;<br/>
                            &lt;/interface&gt;<br/>
                        &lt;/interfaces&gt;<br/>
                    &lt;/area&gt;<br/>
                &lt;/ospf&gt;<br/>
            &lt;/protocols&gt;<br/>
        &lt;/top&gt;<br/>
    &lt;/config&gt;<br/>
&lt;/edit-config&gt;<br/>
&lt;/rpc&gt;
</code></pre></li>
<li><copy-config>
<p>　　将一个库的数据复制到另一个库。 <br/>
　　举例：</p>
<pre><code class="language-text">&lt;rpc message-id=&quot;101&quot;
xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;<br/>
&lt;copy-config&gt;<br/>
    &lt;target&gt;<br/>
        &lt;running/&gt;<br/>
    &lt;/target&gt;<br/>
    &lt;source&gt;<br/>
        &lt;url&gt;https://user:password@example.com/cfg/new.txt&lt;/url&gt;<br/>
    &lt;/source&gt;<br/>
&lt;/copy-config&gt;<br/>
&lt;/rpc&gt;
</code></pre></li>
<li><delete-config>
<p>　　删除一个数据库。但是<running/>库不能被删除。</p>
<pre><code class="language-text">&lt;rpc message-id=&quot;101&quot;
xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;<br/>
&lt;delete-config&gt;<br/>
    &lt;target&gt;<br/>
        &lt;startup/&gt;<br/>
    &lt;/target&gt;<br/>
&lt;/delete-config&gt;<br/>
&lt;/rpc&gt;
</code></pre></li>
<li><lock>
<p>　　获取指定数据库的锁，当某个client获得了指定数据库的锁之后，在其没有释放该锁之前，其余client均不能获得该数据库的锁，也不能对其进行修改操作。同一client也不能在没有释放锁之前，重复申请锁。 <br/>
获取锁的主要目的就是避免并发导致数据冲突。 <br/>
<strong>在执行h3c的配置回滚操作时需要先执行lock操作，参见<a href="http://www.h3c.com/cn/d_201712/1054892_30005_0.htm#_Ref319171075">http://www.h3c.com/cn/d_201712/1054892_30005_0.htm#_Ref319171075</a></strong>1.10.3章节<br/>
　　举例：</p>
<pre><code class="language-text">&lt;rpc message-id=&quot;101&quot;
xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;<br/>
&lt;lock&gt;<br/>
    &lt;target&gt;<br/>
        &lt;running/&gt;<br/>
    &lt;/target&gt;<br/>
&lt;/lock&gt;<br/>
&lt;/rpc&gt;
</code></pre></li>
<li><unlock>
<p>　　释放指定数据库的锁。client只能释放自己持有的锁，不能释放其它client的锁。 <br/>
　　举例：</p>
<pre><code class="language-text">&lt;rpc message-id=&quot;101&quot;
xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;<br/>
&lt;unlock&gt;<br/>
    &lt;target&gt;<br/>
        &lt;running/&gt;<br/>
    &lt;/target&gt;<br/>
&lt;/unlock&gt;<br/>
&lt;/rpc&gt;
</code></pre></li>
<li><close-session>
<p>　　优雅关闭netconf会话，netconf-server将释放该client持有的锁和为其分配的资源，并优雅的关闭与该client链接。所有在<close-session>之后收到的操作均会被忽略。</p></li>
<li><kill-session>
<p>　　强制关闭netconf会话。</p></li>
</ul>

<h4 id="toc_7">内容层</h4>

<p>内容层其实就是我们要向设备发送配置信息，以xml形式体现，但是可以通过yang模型进行建模。<br/>
内容层未指定具体的模型结构，而是指定了一套建模语言–yang。也就是说使用yang定义的数据模型，均可以作为netconf的内容层。所以扩展对netconf来说就是不断的增加和修改yang文件而已</p>

<h2 id="toc_8">how：（如何使用netconf命令）</h2>

<p>python拥有超强大的代码库，使用ncclient下发netconf命令。</p>

<h3 id="toc_9">python ncclient库介绍</h3>

<h4 id="toc_10">Manager API介绍</h4>

<p><em>ManagerAPI是作为ncclient底层RPC交互能力的一个抽象，基本满足了我们配置下发查询的基本需求</em></p>

<p>翻译官方API文档：（英文水平有限，尽量还是阅读英文原文）</p>

<ul>
<li><p>获取能力信息</p></li>
<li><p>get</p></li>
<li><p>get-bluk</p></li>
<li><p>edit-config</p></li>
<li></li>
</ul>

<pre><code class="language-失败返回结果">&lt;env:Envelope xmlns:env=&quot;http://www.w3.org/2003/05/soap-envelope&quot;&gt;
   &lt;env:Body&gt;
      &lt;env:Fault&gt;
         &lt;env:Code&gt;
            &lt;env:Value&gt;env:Sender&lt;/env:Value&gt;
         &lt;/env:Code&gt;
         &lt;env:Reason&gt;
            &lt;env:Text xml:lang=&quot;en&quot;&gt;Invalid session&lt;/env:Text&gt;
         &lt;/env:Reason&gt;
      &lt;/env:Fault&gt;
   &lt;/env:Body&gt;
&lt;/env:Envelope&gt;
</code></pre>

<pre><code class="language-成功返回信息">&lt;env:Envelope xmlns:env=&quot;http://www.w3.org/2003/05/soap-envelope&quot;&gt;
   &lt;env:Header&gt;
      &lt;auth:Authentication env:mustUnderstand=&quot;true&quot; xmlns:auth=&quot;http://www.h3c.com/netconf/base:1.0&quot;&gt;
         &lt;auth:AuthInfo&gt;100001a27b7389ba8e2b68299bfbfef30487&lt;/auth:AuthInfo&gt;
      &lt;/auth:Authentication&gt;
   &lt;/env:Header&gt;
   &lt;env:Body&gt;
      &lt;rpc-reply message-id=&quot;252&quot; xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;
         &lt;ok/&gt;
      &lt;/rpc-reply&gt;
   &lt;/env:Body&gt;
&lt;/env:Envelope&gt;
</code></pre>

<pre><code class="language-text">&lt;env:Envelope xmlns:env=&quot;http://www.w3.org/2003/05/soap-envelope&quot;&gt;
   &lt;env:Header&gt;
      &lt;auth:Authentication env:mustUnderstand=&quot;true&quot; xmlns:auth=&quot;http://www.h3c.com/netconf/base:1.0&quot;&gt;
         &lt;auth:AuthInfo&gt;100001a27b7389ba8e2b68299bfbfef30487&lt;/auth:AuthInfo&gt;
      &lt;/auth:Authentication&gt;
   &lt;/env:Header&gt;
   &lt;env:Body&gt;
      &lt;env:Fault&gt;
         &lt;env:Code&gt;
            &lt;env:Value&gt;env:Receiver&lt;/env:Value&gt;
         &lt;/env:Code&gt;
         &lt;env:Reason&gt;
            &lt;env:Text xml:lang=&quot;en&quot;&gt;bad-attribute&lt;/env:Text&gt;
         &lt;/env:Reason&gt;
         &lt;env:Detail&gt;
            &lt;rpc-error xmlns=&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&gt;
               &lt;error-type&gt;rpc&lt;/error-type&gt;
               &lt;error-tag&gt;bad-attribute&lt;/error-tag&gt;
               &lt;error-severity&gt;error&lt;/error-severity&gt;
               &lt;error-message xml:lang=&quot;en&quot;&gt;The value of attribute &#39;urn:ietf:params:xml:ns:netconf:base:1.0&#39;:&#39;operation&#39; for element &#39;/Envelope/Body[1]/rpc[1]/edit-config[1]/config[1]/top[1]/ACL[1]&#39; is invalid. The value does not match the enumeration.&lt;/error-message&gt;
               &lt;error-info&gt;
                  &lt;bad-element&gt;ACL&lt;/bad-element&gt;
                  &lt;bad-attribute&gt;operation&lt;/bad-attribute&gt;
               &lt;/error-info&gt;
            &lt;/rpc-error&gt;
         &lt;/env:Detail&gt;
      &lt;/env:Fault&gt;
   &lt;/env:Body&gt;
&lt;/env:Envelope&gt;
</code></pre>

<h2 id="toc_11">where：（netconf命令在哪儿使用嘞？）</h2>

<p>neutron作为openstack的网络组建，由于各家云厂商实现不同，有些配置需要下发到设备上，此时netconf就变得炙手可热啦！<br/>
所以，netconf用于neutron操作设备的agent使用。</p>

<h2 id="toc_12">参考资料</h2>

<blockquote>
<p>netconf详解：<br/>
<a href="https://blog.csdn.net/anzheangel/article/details/78885880">https://blog.csdn.net/anzheangel/article/details/78885880</a><br/>
h3c_netconf配置：<br/>
<a href="http://www.h3c.com/cn/d_201906/1208544_30005_0.htm#_Ref336504934">http://www.h3c.com/cn/d_201906/1208544_30005_0.htm#_Ref336504934</a><br/>
xml命名空间解释：<br/>
<a href="http://www.w3school.com.cn/xml/xml_namespaces.asp">http://www.w3school.com.cn/xml/xml_namespaces.asp</a><br/>
<a href="https://blog.csdn.net/mylifeyouwill/article/details/81487348">https://blog.csdn.net/mylifeyouwill/article/details/81487348</a><br/>
ncclient工具API文档：<br/>
<a href="https://ncclient.readthedocs.io/en/latest/manager.html">https://ncclient.readthedocs.io/en/latest/manager.html</a><br/>
ncclient github路径：<br/>
<a href="https://github.com/ncclient/ncclient">https://github.com/ncclient/ncclient</a><br/>
python xml解析库参考：<br/>
<a href="https://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element">https://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element</a></p>
</blockquote>

                        
                      </div>
                  </div>
                </a>
                <div class="read-more clearfix">
                  <div class="more-left left">
                  
                    <span class="date">2019/7/2</span>
                    <span>posted in&nbsp;</span> 
          				  
          					    <span class="posted-in"><a href='%E9%A1%B9%E7%9B%AE%E7%AC%94%E8%AE%B0.html'>项目笔记</a></span>
          				   
                  </div>
                  <div class="more-right right">
                  <span class="comments">
                      

                       
                  </span>
                  </div>
                </div>
              </div><!-- article -->
        
			<div class="article">
                <a class="clearlink" href="15616076768930.html">
                
                  <h1>natgateway功能项目</h1>
                  <div class="a-content">
                      
                      <div class="a-content-text">
                        
                        	<ul>
<li>
<a href="#toc_0">整体框架图</a>
</li>
<li>
<a href="#toc_1">natgateway功能方案</a>
<ul>
<li>
<a href="#toc_2">natgateway neutron plugin实现</a>
</li>
<li>
<a href="#toc_3">natgateway agent实现</a>
<ul>
<li>
<a href="#toc_4">snat功能实现</a>
<ul>
<li>
<a href="#toc_5">snat功能验证</a>
<ul>
<li>
<a href="#toc_6">删除默认网关配置snat验证</a>
</li>
<li>
<a href="#toc_7">snat与eip共存验证</a>
</li>
<li>
<a href="#toc_8">snat与租管互通验证</a>
</li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#toc_9">natgateway agent snat功能接口</a>
</li>
<li>
<a href="#toc_10">dnat功能实现</a>
<ul>
<li>
<ul>
<li>
<a href="#toc_11">验证eip与dnat共存情况下,dnat功能是否可用</a>
</li>
<li>
<a href="#toc_12">验证snat与dnat共存情况下，dnat功能是否可用</a>
</li>
<li>
<a href="#toc_13">租管互通情况下，dnat功能是否可用</a>
</li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#toc_14">natgateway agent dnat功能接口</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>


<h2 id="toc_0">整体框架图</h2>

<p><img src="media/15616076768930/15616234281714.jpg" alt=""/></p>

<h2 id="toc_1">natgateway功能方案</h2>

<ul>
<li>natgateway功能上线之后，将会裁掉默认网关功能，即上线后再创建VPC，则VPC下的vm在未购买eip、snat、dnat的情况下是不能访问外网或者从外网访问的。</li>
<li>关于nat功能上线时，禁止VPC默认网关生效的ACL规则由VCFC下发配置时生效。</li>
<li>为满足租管互通需求，VCFC会在VPC下的默认网关对应的ACL规则添加一条rule即：允许目的ip地址为cloudos地址的报文通过，即允许访问外网。</li>
</ul>

<h3 id="toc_2">natgateway neutron plugin实现</h3>

<ol>
<li>neutron提供PCO调用接口，完成natgatewey的逻辑处理</li>
<li>neutron部分代码需要维护eip与内网ip的关系，存储到neutron数据库</li>
<li><strong>neutron维护nat group索引 16385~65535, VCFC维护 0~16384</strong></li>
</ol>

<h3 id="toc_3">natgateway agent实现</h3>

<ul>
<li>natgateway agent采用脚本的方式实现，即通过脚本向FW下发相关的snat和dnat配置</li>
<li>snat配置能够支持VPC下某个子网能够访问外网</li>
<li>dnat不支持指定协议，所以目前配置支持tcp、udp指定外网地址与端口号与内网地址端口号的映射</li>
</ul>

<h4 id="toc_4">snat功能实现</h4>

<ol>
<li><p>配置snat原则及命令：</p>
<ul>
<li>删除VPC下默认网关ACL对应的permit规则<em>由VCFC创建VPC时配置</em></li>
<li>添加一条ACL规则和一个nat地址组配置，用于存放外网地址信息</li>
<li>在外网接口上将ACL规则与nat地址组规则通过nat outbound绑定</li>
<li>为了区分SDN下发配置与脚本下发配置区别，脚本下载的ACL和nat group规则前缀</li>
</ul>
<pre><code class="language-text">    SDN_ADDR = &#39;UNI_NEUTRON_ADDR_&#39;
    SDN_NAT_ACL = &#39;UNI_NEUTRON_NAT_ACL_&#39;
</code></pre>
<ul>
<li><strong>名称前缀要的字母序列要在默认网关之后，详见snat与租管互通验证</strong></li>
</ul></li>
</ol>

<h5 id="toc_5">snat功能验证</h5>

<h6 id="toc_6">删除默认网关配置snat验证</h6>

<ul>
<li><strong>默认网关删除VM不能访问外网，配置snat能够访问外网</strong></li>
<li>创建一个VPC，添加一个vm，vm能够访问外网。</li>
<li>将默认网关的ACL规则设置为deny,vm不能访问外网</li>
</ul>

<pre><code class="language-text">H3C-acl-ipv4-adv-SDN_NAT_ACL_6c42qr08ji88or3pejd7jssnpc]rule 10000 deny ip vpn-instance 6c42qr08ji88or3pejd7jssnpc
The rule was edited successfully.
[H3C-acl-ipv4-adv-SDN_NAT_ACL_6c42qr08ji88or3pejd7jssnpc]dis th
#
acl advanced name SDN_NAT_ACL_6c42qr08ji88or3pejd7jssnpc
description SDN_ACL_
rule 10000 deny ip vpn-instance 6c42qr08ji88or3pejd7jssnpc
#
return
此时VM 192.168.5.3 地址不能访问外网
</code></pre>

<ul>
<li> 新增一条ACL规则，指定192.168.5.0网段能够放行</li>
</ul>

<pre><code class="language-text">[H3C]acl advanced name SDN_NAT_ACL_6c42qr08ji88or3pejd7jssnpc_1
[H3C-acl-ipv4-adv-SDN_NAT_ACL_6c42qr08ji88or3pejd7jssnpc_1]rule 10001 permit ip vpn-instance 6c42qr08ji88or3pejd7jssnpc source 192.168.5.0 0.0.0.255
[H3C-acl-ipv4-adv-SDN_NAT_ACL_6c42qr08ji88or3pejd7jssnpc_1]dis th
#
acl advanced name SDN_NAT_ACL_6c42qr08ji88or3pejd7jssnpc_1
rule 10001 permit ip vpn-instance 6c42qr08ji88or3pejd7jssnpc source 192.168.5.0 0.0.0.255
#
Return
</code></pre>

<ul>
<li>新增一个nat group（相当于购买一个EIP信息） </li>
</ul>

<pre><code class="language-text">H3C]nat address-group 50 name SDN_ADDR_6c42qr08ji88or3pejd7jssnpc_1
[H3C-address-group-50-SDN_ADDR_6c42qr08ji88or3pejd7jssnpc_1]addr
[H3C-address-group-50-SDN_ADDR_6c42qr08ji88or3pejd7jssnpc_1]address 10.0.46.100 10.0.46.100
</code></pre>

<ul>
<li>将nat group与acl规则绑定并添加到对应的出接口下</li>
</ul>

<pre><code class="language-text">[[H3C-Route-Aggregation2]nat outbound name SDN_NAT_ACL_6c42qr08ji88or3pejd7jssnpc_1 address-group name SDN_ADDR_6c42qr08ji88or3pejd7jssnpc_1 vpn-instance externa
l_vpn
此时192.168.5.3 VM能够ping通外网。
</code></pre>

<h6 id="toc_7">snat与eip共存验证</h6>

<ul>
<li><strong>VM配置EIP功能下，vm能够访问外网，且通过EIP对应的地址转换出去，不会转成snat的eip地址</strong></li>
<li>整体VPC相关配置</li>
</ul>

<pre><code class="language-text">nat static outbound 192.168.6.5 vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 103.36.28.146 vpn-instance external_vpn acl name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip reversible
 ip binding vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
  rule 37 pass vrf 6b825g0sv08dcrt0q1gd16bl6o
 rule 0 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 60000 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 0 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 60000 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 0 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 import ip 192.168.6.0 24 vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
 ip route-static vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 0.0.0.0 0 vpn-instance external_vpn 10.251.179.254 description SDN_ROUTE
 ip route-static vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 192.168.6.0 24 10.251.164.81 description SDN_ROUTE
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o???nat
    
nat address-group 500 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_snat
</code></pre>

<ul>
<li>配置默认网关情况下ping 114.114.114.114 能够正常ping通</li>
</ul>

<pre><code class="language-text">acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
    
nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o vpn-instance external_vpn
    
nat address-group 17 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o
 address 103.36.30.4 103.36.30.4
</code></pre>

<p>转化成默认网关地址<br/>
<img src="media/15616076768930/15616154004930.jpg" alt=""/></p>

<ul>
<li>配置默认网关和VM绑定EIP后能够正常ping通114.114.114.114，nat转换地址为eip地址</li>
</ul>

<pre><code class="language-text">acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o

nat static outbound 192.168.6.5 vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 103.36.28.146 vpn-instance external_vpn acl name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip reversible
</code></pre>

<p><img src="media/15616076768930/15616155237516.jpg" alt=""/></p>

<ul>
<li>配置默认网关为deny或删除acl，且配置eip，能通，转化地址为eip地址</li>
</ul>

<pre><code class="language-text">#
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o
 description SDN_ACL_
 rule 10000 deny ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
#

[H3C-acl-ipv4-adv-SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o]dis this
#
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o
 description SDN_ACL_
#
return
</code></pre>

<p><img src="media/15616076768930/15616155940120.jpg" alt=""/></p>

<ul>
<li>默认网关删除或deny且删除eip配置，配置snat功能，能够ping通，转换地址为snat地址</li>
</ul>

<pre><code class="language-text">#
nat address-group 500 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_snat
 address 10.0.46.100 10.0.46.100
#
return
[H3C-acl-ipv4-adv-SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat]dis this
#
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1 source 192.168.6.0 0.0.0.255
#
return
    
nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_snat vpn-instance external_vpn
    
[H3C-acl-ipv4-adv-SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o]dis this
#
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o
 description SDN_ACL_
#
Return
    
[H3C-acl-ipv4-adv-SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip]dis this
#
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip
#
return
</code></pre>

<p><img src="media/15616076768930/15616156491411.jpg" alt=""/></p>

<ul>
<li>默认网关删除或deny，配置eip地址，配置snat功能，转换地址为eip地址</li>
</ul>

<pre><code class="language-text">#
nat address-group 500 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_snat
 address 10.0.46.100 10.0.46.100
#
return
[H3C-acl-ipv4-adv-SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat]dis this
#
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1 source 192.168.6.0 0.0.0.255
#
return
    
nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_snat vpn-instance external_vpn
    
删除默认网关配置
[H3C-acl-ipv4-adv-SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o]dis this
#
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o
 description SDN_ACL_
#
return
</code></pre>

<p><img src="media/15616076768930/15616158017702.jpg" alt=""/></p>

<h6 id="toc_8">snat与租管互通验证</h6>

<ul>
<li><strong>配置租管互通出方向走默认网关，snat干掉默认网关之后会导致租管互通不通，解决方案如下，后续为验证过程</strong>
<ul>
<li>目前解决方式：在默认网关配置rule，允许目的ip地址为cloudos地址（内网eip地址）的报文通过</li>
<li>最终解决方案：重新配置一条ACL与nat group，ACL下的rule为允许目的ip地址为cloudos地址（内网eip地址）的报文通过</li>
</ul></li>
<li>  配置了eip也配置了租管互通的100.64网段的网关信息，配置如下：</li>
</ul>

<pre><code class="language-text">nat address-group 501 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_zght
 nat static outbound 192.168.6.5 vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 103.36.28.146 vpn-instance external_vpn acl name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip reversible
nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_snat vpn-instance external_vpn
 nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_zght address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_zght vpn-instance external_vpn
ip route-static vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 192.168.6.0 24 10.251.164.81 description SDN_ROUTE
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o source 192.168.6.0 0.0.0.255
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_zght
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o destination 100.64.9.0 0.0.0.
</code></pre>

<p>此时显示的IP地址转换出来为EIP的地址即103.36.28.146<br/>
<img src="media/15616076768930/15616159813542.jpg" alt=""/></p>

<ul>
<li>  未配置eip的情况下租管互通的地址转换如下图：<br/>
租管互通配置的acl规则只指定目的地址的情况下地址转换会被snat规则替代，如下：</li>
</ul>

<pre><code class="language-text">[H3C-acl-ipv4-adv-SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip]dis this
#
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip
 rule 10000 deny ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
#
return

#
nat address-group 501 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_zght
 address 100.64.192.100 100.64.192.100
#
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_zght
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o destination 100.64.9.0 0.0.0.
</code></pre>

<p>如上所示只指定了目的未指定源地址，则会出现转换成snat配置的那条规则：<br/>
<img src="media/15616076768930/15616164678217.jpg" alt=""/></p>

<ul>
<li>未配置eip的情况下租管互通的地址转换如下图：</li>
</ul>

<pre><code class="language-text">租管互通的acl规则配置：
#
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_zght
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o source 192.168.6.0 0.0.0.255 destination 100.64.9.0 0.0.0.7
#

ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
nat address-group 17 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o
nat address-group 500 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_snat
nat address-group 501 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_zght
 nat static outbound 192.168.6.5 vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 103.36.28.146 vpn-instance external_vpn acl name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip reversible
 ip binding vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
 nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o vpn-instance external_vpn
 nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_snat vpn-instance external_vpn
 nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_zght address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_zght vpn-instance external_vpn
 rule 37 pass vrf 6b825g0sv08dcrt0q1gd16bl6o
 rule 0 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 60000 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 0 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 60000 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 0 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 import ip 192.168.6.0 24 vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
 ip route-static vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 0.0.0.0 0 vpn-instance external_vpn 10.251.179.254 description SDN_ROUTE
 ip route-static vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 192.168.6.0 24 10.251.164.81 description SDN_ROUTE
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip
 rule 10000 deny ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o source 192.168.6.0 0.0.0.255
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_zght
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o source 192.168.6.0 0.0.0.255 destination 100.64.9.0 0.0.0.7
</code></pre>

<p>snat规则不变同上,转换后地址如下图所示，仍然未转换到租管互通的100网段地址<br/>
<img src="media/15616076768930/15616165723606.jpg" alt=""/></p>

<ul>
<li>将租管互通的acl规则名称修改为在snat规则之上情况下测试结果。
<ul>
<li>如下配置，与3的唯一区别是outbound的ACL名称租管互通的名称排在SNAT的功能之前，此时租管互通的规则生效，如抓包结果所示转换为租管互通的100网段地址。</li>
</ul></li>
</ul>

<pre><code class="language-text">ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
nat address-group 17 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o
nat address-group 500 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_snat
nat address-group 501 name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_zght
 nat static outbound 192.168.6.5 vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 103.36.28.146 vpn-instance external_vpn acl name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip reversible
 ip binding vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
 nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o vpn-instance external_vpn
 nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_azght address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_zght vpn-instance external_vpn
 nat outbound name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat address-group name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_snat vpn-instance external_vpn
 rule 37 pass vrf 6b825g0sv08dcrt0q1gd16bl6o
 rule 0 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 60000 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 0 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 60000 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 rule 0 pass vrf 6b825g0sv08dcrt0q1gd16bl6o counting
 import ip 192.168.6.0 24 vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
 ip route-static vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 0.0.0.0 0 vpn-instance external_vpn 10.251.179.254 description SDN_ROUTE
 ip route-static vpn-instance 6b825g0sv08dcrt0q1gd16bl6o 192.168.6.0 24 10.251.164.81 description SDN_ROUTE
acl advanced name SDN_ADDR_6b825g0sv08dcrt0q1gd16bl6o_zght
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_azght
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o source 192.168.6.0 0.0.0.255 destination 100.64.9.0 0.0.0.7
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_eip
 rule 10000 deny ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o
acl advanced name SDN_NAT_ACL_6b825g0sv08dcrt0q1gd16bl6o_snat
 rule 10000 permit ip vpn-instance 6b825g0sv08dcrt0q1gd16bl6o source 192.168.6.0 0.0.0.255
</code></pre>

<p><img src="media/15616076768930/15616166251616.jpg" alt=""/></p>

<h4 id="toc_9">natgateway agent snat功能接口</h4>

<ul>
<li><p>creat</p>
<ul>
<li>URL <a href="http://10.0.46.156:30458/snat/create">http://10.0.46.156:30458/snat/create</a></li>
<li>PUT 方法</li>
<li>JSON data:</li>
</ul>
<pre><code class="language-text">{
    &quot;vpn-instance&quot;: &quot;ly1234567890&quot;,<br/>
    &quot;eip&quot;: &quot;1.1.1.1&quot;,<br/>
    &quot;address-group&quot;: 65000,<br/>
    &quot;interfacename&quot;: &quot;Ten-GigabitEthernet1/2/1&quot;,<br/>
    &quot;subnet_array&quot;: [{&quot;ip&quot;: &quot;192.168.1.1&quot;, &quot;netmask&quot;: 24}]<br/>
}
</code></pre></li>
<li><p>delete</p>
<ul>
<li>URL <a href="http://10.0.46.156:30458/snat/delete">http://10.0.46.156:30458/snat/delete</a></li>
<li>PUT 方法</li>
<li>JSON </li>
</ul>
<pre><code class="language-text">{
    &quot;vpn-instance&quot;: &quot;ly1234567890&quot;,<br/>
    &quot;address-group&quot;: 65000,<br/>
    &quot;interfacename&quot;: &quot;Ten-GigabitEthernet1/2/1&quot;<br/>
}
</code></pre></li>
<li><p>update</p>
<ul>
<li>URL <a href="http://10.0.46.156:30458/snat/update">http://10.0.46.156:30458/snat/update</a></li>
<li>PUT方法</li>
<li>JSON</li>
</ul>
<pre><code class="language-text">{
    &quot;vpn-instance&quot;: &quot;ly1234567890&quot;,<br/>
    &quot;eip&quot;: &quot;1.1.1.2&quot;,<br/>
    &quot;address-group&quot;: 65000,<br/>
    &quot;interfacename&quot;: &quot;Ten-GigabitEthernet1/2/1&quot;,<br/>
    &quot;subnet_array&quot;: [{&quot;ip&quot;: &quot;192.168.2.0&quot;, &quot;netmask&quot;: 24},<br/>
    {&quot;ip&quot;: &quot;192.168.1.0&quot;, &quot;netmask&quot;: 24}]<br/>
}
</code></pre></li>
</ul>

<h4 id="toc_10">dnat功能实现</h4>

<p><strong>dnat功能即下发一条nat server规则即在防火墙上添加DNAT规则如下</strong></p>

<pre><code class="language-text">nat server protocol tcp global 100.64.192.11 54321 vpn-instance external_vpn inside 172.17.1.2 22 vpn-instance 1e54vevhk09j9qo6jdug4tlkgp
</code></pre>

<p>首先需要有一个非VPC网络能够访问VPC网络的环境。当前，在10.0.46.156上，已经存在可用网络，组网图如下：<br/>
<img src="media/15616076768930/15616167139442.jpg" alt=""/></p>

<p>如图所示：<br/>
Border-&gt;Switch属于非VPC网络<br/>
而Border-&gt;Spine属于VPC网络</p>

<p>此时在PC上通过ssh能够登录到VM172.17.1.2的设备上。<br/>
<img src="media/15616076768930/15616167914968.jpg" alt=""/><br/>
抓包如下：<br/>
<img src="media/15616076768930/15616168068085.jpg" alt=""/></p>

<h6 id="toc_11">验证eip与dnat共存情况下,dnat功能是否可用</h6>

<ul>
<li>通过CloudOS将VM绑定EIP(100.64.192.11)</li>
<li>下发命令配置DNAT功能(100.64.192.12:54321.  &lt;-&gt; 172.17.1.2:22)</li>
<li>查看ssh登录结果 </li>
<li><strong>EIP和dnat同时配置时，EIP和dnat均生效，均能访问对应内网服务</strong></li>
</ul>

<p><img src="media/15616076768930/15616168648356.jpg" alt=""/><br/>
<img src="media/15616076768930/15616168742201.jpg" alt=""/><br/>
<img src="media/15616076768930/15616168844698.jpg" alt=""/></p>

<ul>
<li>使用EIP地址也能ssh登录到VM ssh root@100.64.192.11</li>
</ul>

<p><img src="media/15616076768930/15616169156020.jpg" alt=""/></p>

<h6 id="toc_12">验证snat与dnat共存情况下，dnat功能是否可用</h6>

<ul>
<li>配置snat功能，未配置EIP功能</li>
<li>下发命令配置DNAT功能</li>
<li>查看ssh登录结果，通过VM ping外部PC地址
<ul>
<li>snat功能生效</li>
<li>dnat功能生效, 且eip功能失效</li>
<li><strong>snat与dnat不会相互影响，snat能够访问外网，dnat能够被外网访问指定端口</strong></li>
</ul></li>
</ul>

<p><img src="media/15616076768930/15616169845167.jpg" alt=""/><br/>
<img src="media/15616076768930/15616169901270.jpg" alt=""/><br/>
<img src="media/15616076768930/15616170452907.jpg" alt=""/></p>

<h6 id="toc_13">租管互通情况下，dnat功能是否可用</h6>

<ul>
<li>由于租管互通由VM-&gt;Cloudos走的是默认网关功能，与DNAT无关，顾不进行测试。</li>
</ul>

<h4 id="toc_14">natgateway agent dnat功能接口</h4>

<ul>
<li><p>create</p>
<ul>
<li>URL <a href="http://10.0.46.156:30458/dnat/create">http://10.0.46.156:30458/dnat/create</a></li>
<li>PUT 方法</li>
<li>JSON data</li>
</ul>
<pre><code class="language-text">{
    &quot;vpn-instance&quot;: &quot;ly1234567890&quot;,<br/>
    &quot;eip_port&quot;: {&quot;ip&quot;: &quot;192.168.1.1&quot;, &quot;port&quot;: 2222},<br/>
    &quot;ip_port&quot;: {&quot;ip&quot;: &quot;192.168.1.1&quot;, &quot;port&quot;: 2222},<br/>
    &quot;interfacename&quot;: &quot;Ten-GigabitEthernet1/2/1&quot;<br/>
}
</code></pre></li>
<li><p>delete</p>
<ul>
<li>URL <a href="http://10.0.46.156:30458/dnat/delete">http://10.0.46.156:30458/dnat/delete</a></li>
<li>PUT 方法</li>
<li>JSON data</li>
</ul>
<pre><code class="language-text">{
    &quot;vpn-instance&quot;: &quot;ly1234567890&quot;,<br/>
    &quot;eip_port&quot;: {&quot;ip&quot;: &quot;192.168.1.1&quot;, &quot;port&quot;: 2222},<br/>
    &quot;interfacename&quot;: &quot;Ten-GigabitEthernet1/2/1&quot;<br/>
} 
</code></pre></li>
<li><p>update</p>
<ul>
<li>URL <a href="http://10.0.46.156:30458/dnat/update">http://10.0.46.156:30458/dnat/update</a></li>
<li>PUT 方法</li>
<li>JSON data</li>
</ul>
<pre><code class="language-text">{
    &quot;vpn-instance&quot;: &quot;ly1234567890&quot;,<br/>
    &quot;eip_port_old&quot;: {&quot;ip&quot;: &quot;192.168.1.1&quot;, &quot;port&quot;: 3333},<br/>
    &quot;eip_port_new&quot;: {&quot;ip&quot;: &quot;192.168.1.1&quot;, &quot;port&quot;: 2222},<br/>
    &quot;ip_port&quot;: {&quot;ip&quot;: &quot;192.168.1.1&quot;, &quot;port&quot;: 2222},<br/>
    &quot;interfacename&quot;: &quot;Ten-GigabitEthernet1/2/1&quot;<br/>
}
</code></pre></li>
</ul>

                        
                      </div>
                  </div>
                </a>
                <div class="read-more clearfix">
                  <div class="more-left left">
                  
                    <span class="date">2019/6/27</span>
                    <span>posted in&nbsp;</span> 
          				  
          					    <span class="posted-in"><a href='%E9%A1%B9%E7%9B%AE%E7%AC%94%E8%AE%B0.html'>项目笔记</a></span>
          				   
                  </div>
                  <div class="more-right right">
                  <span class="comments">
                      

                       
                  </span>
                  </div>
                </div>
              </div><!-- article -->
        
              


			<div class="row">
			  <div class="large-6 columns">
			  <p class="text-left" style="padding-top:25px;">
			   
			  </p>
			  </div>
			  <div class="large-6 columns">
			<p class="text-right" style="padding-top:25px;">
			
			</p>
			  </div>
			</div>
		</div>
	</div><!-- large 8 -->

 <div class="large-4 medium-4 columns">
  <div class="hide-for-small">
    <div id="sidebar" class="sidebar">
          <div id="site-info" class="site-info">
            
                <h1>NeilBlog</h1>
                <div class="site-des"></div>
                <div class="social">











  <a target="_blank" class="rss" href="atom.xml" title="RSS">RSS</a>
                
              	 </div>
          	</div>

             

              <div id="site-categories" class="side-item ">
                <div class="side-header">
                  <h2>Categories</h2>
                </div>
                <div class="side-content">

      	<p class="cat-list">
        
            <a href="Python.html"><strong>Python</strong></a>
        
            <a href="opentstack-neutron.html"><strong>opentstack-neutron</strong></a>
        
            <a href="%E6%8A%80%E6%9C%AF%E5%91%A8%E8%BE%B9.html"><strong>技术周边</strong></a>
        
            <a href="%E9%A1%B9%E7%9B%AE%E7%AC%94%E8%AE%B0.html"><strong>项目笔记</strong></a>
         
        </p>


                </div>
              </div>

              <div id="site-categories" class="side-item">
                <div class="side-header">
                  <h2>Recent Posts</h2>
                </div>
                <div class="side-content">
                <ul class="posts-list">
	      
		      
			      <li class="post">
			        <a href="15623333744762.html">bytes/string转换</a>
			      </li>
		     
		  
		      
			      <li class="post">
			        <a href="15622929808447.html">netconf client通信框架</a>
			      </li>
		     
		  
		      
			      <li class="post">
			        <a href="15621228986145.html">devstack 安装openstack</a>
			      </li>
		     
		  
		      
			      <li class="post">
			        <a href="15620552731750.html">neutron agent 使用netconf向设备下发配置</a>
			      </li>
		     
		  
		      
			      <li class="post">
			        <a href="15620392963346.html">loggging模块</a>
			      </li>
		     
		  
		      
		  
		      
		  
		      
		  
		      
		  
		      
		   
		  		</ul>
                </div>
              </div>
        </div><!-- sidebar -->
      </div><!-- hide for small -->
</div><!-- large 4 -->

</div><!-- row -->

 <div class="page-bottom clearfix">
  <div class="row">
   <p class="copyright">Copyright &copy; 2015
Powered by <a target="_blank" href="http://www.mweb.im">MWeb</a>,&nbsp; 
Theme used <a target="_blank" href="http://github.com">GitHub CSS</a>.</p>
  </div>
</div>

        </section>
      </div>
    </div>

  
    

    <script src="asset/js/foundation.min.js"></script>
    <script>
      $(document).foundation();
      function fixSidebarHeight(){
        var w1 = $('.markdown-body').height();
          var w2 = $('#sidebar').height();
          if (w1 > w2) { $('#sidebar').height(w1); };
      }
      $(function(){
        fixSidebarHeight();
      })
      $(window).load(function(){
          fixSidebarHeight();
      });
     
    </script>

    
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script><script type="text/x-mathjax-config">MathJax.Hub.Config({TeX: { equationNumbers: { autoNumber: "AMS" } }});</script>


  </body>
</html>
